#include <stdatomic.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <time.h>

typedef struct {
    atomic_bool write_flag;    // 原子写标志
    atomic_size_t write_count; // 写操作计数
    atomic_size_t read_count;  // 读操作计数
    size_t buffers[2];         // 双缓冲区
} pipo_t;

// 初始化结构体
#define PIPOTO_INIT {.write_flag = false}

// 写入线程函数
void* writer(void* arg) {
    pipo_t* ctx = arg;
    size_t data = 0;
    
    while(1) {
        // 获取当前写入缓冲区索引
        bool write_idx = !ctx->write_flag;
        
        // 模拟数据写入
        ctx->buffers[write_idx] = ++data;
        
        // 原子切换写入标志
        ctx->write_flag = write_idx;
        
        // 增加写计数器
        atomic_fetch_add(&ctx->write_count, 1);
        
        //usleep(100); // 控制写入速度
    }
    return NULL;
}

// 读取线程函数
void* reader(void* arg) {
    pipo_t* ctx = arg;
    
    while(1) {
        // 获取当前可读缓冲区
        bool read_idx = ctx->write_flag;
        
        // 读取数据
        size_t val = ctx->buffers[read_idx];
        (void)val; // 使用值避免优化
        
        // 增加读计数器
        atomic_fetch_add(&ctx->read_count, 1);
        
        //usleep(100); // 控制读取速度
    }
    return NULL;
}

// 统计线程函数
void* stats(void* arg) {
    pipo_t* ctx = arg;
    struct timespec ts = {.tv_sec = 1, .tv_nsec = 0};
    
    while(1) {
        nanosleep(&ts, NULL);
        size_t wc = atomic_exchange(&ctx->write_count, 0);
        size_t rc = atomic_exchange(&ctx->read_count, 0);
        printf("Write: %zu/s\tRead: %zu/s\n", wc, rc);
    }
}

int main() {
    pipo_t ctx = PIPOTO_INIT;
    pthread_t writer_th, reader_th, stats_th;

    pthread_create(&writer_th, NULL, writer, &ctx);
    pthread_create(&reader_th, NULL, reader, &ctx);
    pthread_create(&stats_th, NULL, stats, &ctx);

    pthread_join(writer_th, NULL);
    pthread_join(reader_th, NULL);
    pthread_join(stats_th, NULL);

    return 0;
}
